package cn.tedu.mall.front.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.front.service.IFrontCategoryService;
import cn.tedu.mall.pojo.front.entity.FrontCategoryEntity;
import cn.tedu.mall.pojo.front.vo.FrontCategoryTreeVO;
import cn.tedu.mall.pojo.product.vo.CategoryStandardVO;
import cn.tedu.mall.product.service.front.IForFrontAttributeService;
import cn.tedu.mall.product.service.front.IForFrontCategoryService;
import cn.tedu.mall.product.service.front.IForFrontSkuService;
import cn.tedu.mall.product.service.front.IForFrontSpuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author liyang
 * @version 1.0
 * @package cn.tedu.mall.front.service.impl
 * @file FrontCategoryServiceImpl.java
 * @description
 * @time 2025/1/4 下午10:40
 */
@Service
@Slf4j
public class FrontCategoryServiceImpl implements IFrontCategoryService {

    @DubboReference
    private IForFrontCategoryService dubboCategoryService;

    @Autowired
    private RedisTemplate redisTemplate;
    // 分类树
    public static final String CATEGORY_TREE_KEY="category_tree";



    @Override
    public FrontCategoryTreeVO categoryTree() {
        if(redisTemplate.hasKey(CATEGORY_TREE_KEY)){
            // 快捷键强转
            FrontCategoryTreeVO<FrontCategoryEntity> treeVO = (FrontCategoryTreeVO<FrontCategoryEntity>) redisTemplate.boundValueOps(CATEGORY_TREE_KEY).get();
            return treeVO;
        }
        List<CategoryStandardVO> categoryList = dubboCategoryService.getCategoryList();
        FrontCategoryTreeVO<FrontCategoryEntity> treeVO = initTree(categoryList);
        redisTemplate.boundValueOps(CATEGORY_TREE_KEY).set(treeVO,1, TimeUnit.MINUTES);
        return treeVO;
    }

    private FrontCategoryTreeVO<FrontCategoryEntity> initTree(List<CategoryStandardVO> categoryList) {
        Map<Long,List<FrontCategoryEntity>> map=new HashMap<>();
        log.info("准备构建三级分类树，分类对象数量为：{}",categoryList.size());
        for(CategoryStandardVO categoryStandardVO:categoryList){
            FrontCategoryEntity frontCategoryEntity=new FrontCategoryEntity();
            BeanUtils.copyProperties(categoryStandardVO,frontCategoryEntity);
            Long parentId=frontCategoryEntity.getParentId();
            if(!map.containsKey(parentId)){
                List<FrontCategoryEntity> value = new ArrayList<>();
                value.add(frontCategoryEntity);
                map.put(parentId,value);
            }else{
                map.get(parentId).add(frontCategoryEntity);
            }
        }
        List<FrontCategoryEntity> firstLevels=map.get(0L);
        if(firstLevels==null || firstLevels.isEmpty()){
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"没有一级分类对象");
        }
        for(FrontCategoryEntity oneLevel : firstLevels){
            Long secondLevelParentId= oneLevel.getId();
            List<FrontCategoryEntity> secondLevels=map.get(secondLevelParentId);
            if(secondLevels==null||secondLevels.isEmpty()){
                log.warn("当前二级分类没有内容：{}",secondLevelParentId);
                continue;
            }
            for(FrontCategoryEntity twoLevel : secondLevels){
                Long thirdLevelParentId=twoLevel.getId();
                List<FrontCategoryEntity> thirdLevels=map.get(thirdLevelParentId);
                if(thirdLevels==null||thirdLevels.isEmpty()){
                    log.warn("当前二级分类没有三级分类内容：{}",thirdLevelParentId);
                    continue;
                }
                twoLevel.setChildrens(thirdLevels);
            }
            oneLevel.setChildrens(secondLevels);
        }
        FrontCategoryTreeVO<FrontCategoryEntity> treeVO= new FrontCategoryTreeVO<>();
        treeVO.setCategories(firstLevels);
        return treeVO;
    }
}
